package academic.emailClient.persistence;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.UUID;

import academic.emailClient.model.entities.Message;
import academic.emailClient.model.entities.MessageAttributes;
import academic.emailClient.model.entities.MessageBuilder;

/**
 * Class that allows persist messages in a directory as a plain text files
 * @author Alejandra
 *
 */
public class MessageFileDAO {
	
	private static final String SEPARATOR = "/";
	private static final String NEWLINE = "\n";
	private static final String DATE_FORMAT = "yyMMddHHmmss"; 
	
	/**
	 * Creates an email in a determined directory
	 * @param path Directory where the email should be saved
	 * @param message Message that contains the information that must be persisted
	 * @return Returns true if the message is created
	 */
	public static boolean create(String path, Message message){
		File file = new File(path, message.getId().toString());
		
		try {
			//Validates if file exists to create it
			if (file.exists()){
				return false;
			}
			
			file.createNewFile();
			writeInFile(file, message);				
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return true;	
	}
	
	/**
	 * Updates a message that it's been previously created in the directory
	 * @param path Directory where the email is saved
	 * @param message Message  that contains the information that must be persisted
	 * @return Returns true if the message is updated
	 */
	public static boolean update(String path, Message message){
		File file = new File(path, message.getId().toString());
		
		try {
			//Validates if file exists to create it
			if (!file.exists()){
				return false;
			}
			writeInFile(file, message);		
				
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return true;			
	}
	
	/**
	 * Reads a message from a plain file in a directory giving the file path and the name of the file
	 * @param path  Absolute path of the message
	 * @param name Message filename
	 * @return Returns the message that was read from the file
	 */
	public static Message read(String path, String name){
		File file = new File(path, name);
		FileReader reader;
		BufferedReader buffer;
		MessageBuilder message = new MessageBuilder();
		Message readMessage;
		String line;
		String bodyMessage = "";
		
		try {
			// Validates if file exists to create it
			if (file.exists()){
				reader = new FileReader(file);
				buffer = new BufferedReader(reader);
			// Reading line by line
				message = message.withId(UUID.fromString(name));
				while ((line = buffer.readLine()) != null){
					String values[] = line.split(SEPARATOR);
					if (values.length != 1){
						// 	Reads every attribute
						if ( values[0].equals(MessageAttributes.FROM.toString()))
							message = message.withFrom(values[1]);
						else if (values[0].equals(MessageAttributes.TO.toString()))
							message = message.withTo(values[1]);
						else if (values[0].equals(MessageAttributes.CC.toString()))
							message = message.withCc(values[1]);
						else if (values[0].equals(MessageAttributes.SUBJECT.toString()))
							message = message.withSubject(values[1]);
						else if (values[0].equals(MessageAttributes.BODY_MESSAGE.toString()))
							bodyMessage = values[1];
						else if (values[0].equals(MessageAttributes.DATE.toString())){
							DateFormat df = new SimpleDateFormat(DATE_FORMAT);
							message.withDate(df.parse(values[1]));
						}
					}
					else {
						bodyMessage += line;
					}
				}
				message.withBodyMessage(bodyMessage);
				buffer.close();
				reader.close();
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}
		readMessage = message.build();
		return readMessage;

	}

	/**
	 * Deletes a message from the directory
	 * @param path Directory where the message is saved
	 * @param name Message filename
	 * @return Returns true if the message is deleted
	 */
	public static boolean delete(String path, String name){
		File file = new File(path, name);
		// If the directory exists, deletes it
		return file.delete();
	}

	
	/**
	 * Private methods
	 */
	
	/**
	 * Writes a Message object in a plain text file
	 * @param file File where message should be written
	 * @param message 
	 * @throws IOException
	 */	
	private static void writeInFile(File file, Message message) throws IOException{
		BufferedWriter buffer;
		FileWriter writer;
		
		//Making message plain
		writer = new FileWriter(file);
		buffer = new BufferedWriter(writer);
		buffer.write(MessageAttributes.FROM + SEPARATOR + message.getFrom() + NEWLINE);
		buffer.write(MessageAttributes.TO + SEPARATOR + message.getTo() + NEWLINE);
		buffer.write(MessageAttributes.CC + SEPARATOR + message.getCc() + NEWLINE);
		buffer.write(MessageAttributes.SUBJECT + SEPARATOR + message.getSubject() + NEWLINE);
		buffer.write(MessageAttributes.BODY_MESSAGE + SEPARATOR + message.getBodyMessage() + NEWLINE);
		
		DateFormat df = new SimpleDateFormat(DATE_FORMAT);
		buffer.write(MessageAttributes.DATE + SEPARATOR + df.format(message.getDate()) + NEWLINE);
		
		buffer.flush();
		buffer.close();
		writer.close();
	}

		
	public static void main(String[] args){
		
	}
	
}
